﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;
using System.ComponentModel;
using System.Collections.ObjectModel;
using System.Linq;

using C1.Phone;


namespace ControlExplorer
{
    public class ViewModel
        : INotifyPropertyChanged
    {
        #region Singleton implementation

        public static ViewModel Instance { get; private set; }

        static ViewModel()
        {
            Instance = new ViewModel();
        }

        #endregion

        public List<ControlViewModel> Controls = new List<ControlViewModel>();
        public ObservableCollection<CategoryViewModel> Categories = new ObservableCollection<CategoryViewModel>();


        private ViewModel()
        {
            //InheritPhoneTheme = false;
            ControlsVersion = typeof(C1.Phone.C1TextBoxBase).Assembly.FullName.Split(',')[1].Replace(" Version=", "");

            // fill controls data
            #region Data

            Controls.Add(new ControlViewModel("Calendar")
            {
                SampleSpecs =
                {
                    new SampleSpec() 
                    { 
                        Title = "default view",
                        FullTypeName = "ControlExplorer.Controls.Calendar.CalendarDemo",
                        Thumbnail = "calendarDefaultView",
                        Description = "Shows the C1Calendar control with default appearance options and some bolded dates.",
                    },
                    new SampleSpec() 
                    { 
                        Title = "bolded days",
                        FullTypeName = "ControlExplorer.Controls.Calendar.BoldedDayTemplate",
                        Thumbnail = "calendarBoldedDays",
                        Description = "The C1Calendar control allows to set custom DataTemplate to represent bolded days. Use C1Calendar.BoldedDaySlotTemplate property to alter appearance of all bolded days.",
                    },
                    new SampleSpec() 
                    { 
                        Title = "custom days",
                        FullTypeName = "ControlExplorer.Controls.Calendar.DaySlotTemplateSelector",
                        Thumbnail = "calendarCustomDays",
                        Description = "Use DataTemplate selectors to customize calendar days. Supply custom appearance for weekends, today date, holidays or any other days.",
                    },
                    new SampleSpec() 
                    { 
                        Title = "custom data",
                        FullTypeName = "ControlExplorer.Controls.Calendar.CustomData",
                        Thumbnail = "calendarCustomData",
                        Description = "Bind calendar to custom data and use custom BoldedDaySlotTemplate to show information about events. Double tap on day to review detailed information about events.",
                    },
              },
                Categories = { ControlCat.all, ControlCat.favorites }
            });
            Controls.Add(new ControlViewModel("Chart")
            {
                SampleSpecs =
                {
                    new SampleSpec() { Title = "gallery", FullTypeName = "ControlExplorer.Controls.Chart.Gallery", Thumbnail = "chartGallery", Description = "See all supported chart types including bar, column, pie, area, line and scatter." },
                    new SampleSpec() { Title = "static labels", FullTypeName = "ControlExplorer.Controls.Chart.Labels", Thumbnail = "chartLabels", Description = "See static values displayed as labels on each plot element." },
                    new SampleSpec() { Title = "popup labels", FullTypeName = "ControlExplorer.Controls.Chart.PopupLabels", Thumbnail = "chartPopupLabels", Description = "See values displayed as pop-ups when you tap a plot element." },
                    new SampleSpec() { Title = "pie spin", FullTypeName = "ControlExplorer.Controls.Chart.PieSpin", Thumbnail = "chartPieSpin", Description = "Shows a pie chart that spins around its center like a wheel." },
                    new SampleSpec() { Title = "selection", FullTypeName = "ControlExplorer.Controls.Chart.Selection", Thumbnail = "chartSelection", Description = "Selection support for data sources with ICollectionView." },
                    new SampleSpec() { Title = "interaction", FullTypeName = "ControlExplorer.Controls.Chart.InteractiveChart", Thumbnail = "chartInteraction", Description = "Zoom, scale and pan a large chart by touch." },
                    new SampleSpec() { Title = "financial", FullTypeName = "ControlExplorer.Controls.Chart.FinancialChart", Thumbnail = "chartFinancial", Description = "Shows a candle chart with High-Low -Open-Close data series." },
                    new SampleSpec() { Title = "dynamic", FullTypeName = "ControlExplorer.Controls.Chart.Dynamic", Thumbnail = "chartDynamic", Description = "Shows live data as it happens." },
                    new SampleSpec() { Title = "legend checkbox", FullTypeName = "ControlExplorer.Controls.Chart.LegendCheckBox", Thumbnail = "chartLegendCheckBox", Description = "Custom legend template with check box that controls series visibility." },
                    new SampleSpec() { Title = "multiple axes", FullTypeName = "ControlExplorer.Controls.Chart.DependentAxes", Thumbnail = "chartMultipleAxes", Description = "Display multiple, dependent Y-axes with different units of measure." },
                    new SampleSpec() { Title = "animation", FullTypeName = "ControlExplorer.Controls.Chart.Animation", Thumbnail = "chartAnimation", Description = "See plot elements animate on load." },
                    new SampleSpec() { Title = "aggregates", FullTypeName = "ControlExplorer.Controls.Chart.AggregateChart", Thumbnail = "chartAggregates", Description = "Built-in aggregation features allow you to quickly summarize data points." },
                },
                Categories = { ControlCat.all, ControlCat.favorites }
            });
            Controls.Add(new ControlViewModel("ContextMenu")
            {
                SampleSpecs =
                {
                    new SampleSpec() { Title = "", FullTypeName = "ControlExplorer.Controls.ContextMenu.ContextMenuDemo", Description = "" }
                },
                Categories = { ControlCat.all }
            });
            Controls.Add(new ControlViewModel("DateTimePicker")
            {
                SampleSpecs =
                {
                    new SampleSpec() { Title = "", FullTypeName = "ControlExplorer.Controls.DateTimePicker.DateTimePickerDemo", Description = "" }
                },
                Categories = { ControlCat.all, ControlCat.input }
            });
            Controls.Add(new ControlViewModel("Excel")
            {
                SampleSpecs =
                {
                    //new SampleSpec() { Title = "", FullTypeName = "ControlExplorer.Controls.Excel.DemoExcelText", Description = "" },
                    new SampleSpec() { Title = "", FullTypeName = "ControlExplorer.Controls.Excel.DemoExcel", Description = "" },
                },
                Categories = { ControlCat.all, ControlCat.libraries }
            });
            Controls.Add(new ControlViewModel("FlexGrid")
            {
                SampleSpecs =
                {
                    new SampleSpec() { Title = "editing", FullTypeName = "ControlExplorer.Controls.FlexGrid.FlexGridDemo", Thumbnail = "flexgridEditing", Description = "See how to interact with FlexGrid and edit cells." },
                    new SampleSpec() { Title = "sorting & filtering", FullTypeName = "ControlExplorer.Controls.FlexGrid.SortingFiltering", Thumbnail = "flexgridSort", Description = "See how to implement filtering, sorting and even multiple column sorting using our API." },
                },
                Categories = { ControlCat.all, ControlCat.favorites, ControlCat.data }
            });
            Controls.Add(new ControlViewModel("Gauges")
            {
                SampleSpecs =
                {
                    new SampleSpec() { Title = "radial", FullTypeName = "ControlExplorer.Controls.Gauge.RadialGauge", Thumbnail = "gaugeRadialGauge", Description = "See a basic radial gauge with ranges and a Metro theme." },
                    new SampleSpec() { Title = "linear", FullTypeName = "ControlExplorer.Controls.Gauge.LinearGauge", Thumbnail = "gaugeLinearGauge", Description = "See a vertical linear gauge with ranges and a Metro theme." },
                    new SampleSpec() { Title = "ruler", FullTypeName = "ControlExplorer.Controls.Gauge.RulerGauge", Thumbnail = "gaugeRulerGauge", Description = "See a simple linear gauge styled to look like a ruler." },
                    new SampleSpec() { Title = "speedometer", FullTypeName = "ControlExplorer.Controls.Gauge.SpeedometerGauge", Thumbnail = "gaugeSpeedometerGauge", Description = "See a styled speedometer gauge with animation." },
                    new SampleSpec() { Title = "volume", FullTypeName = "ControlExplorer.Controls.Gauge.VolumeGauge", Thumbnail = "gaugeVolumeGauge", Description = "See a rectangular fuel gauge with animation." }
                },
                Categories = { ControlCat.all, ControlCat.favorites, ControlCat.data }
            });
            Controls.Add(new ControlViewModel("Imaging")
            {
                SampleSpecs =
                {
                    new SampleSpec() { Title = "gif", FullTypeName = "ControlExplorer.Controls.Imaging.GifImages", Thumbnail = "imagingGif", Description = "Render animated GIF files using the C1GifImage class." },
                    new SampleSpec() { Title = "manipulation", FullTypeName = "ControlExplorer.Controls.Imaging.ImageManipulation", Thumbnail = "imagingManipulation", Description = "Crop and manipulate pictures using the C1Bitmap class." },
                },
                Categories = { ControlCat.all, ControlCat.libraries }
            });
            Controls.Add(new ControlViewModel("Input")
            {
                SampleSpecs =
                {
                    new SampleSpec() { Title = "masked", FullTypeName = "ControlExplorer.Controls.MaskedTextBox.MaskedTextBoxDemo", Thumbnail="inputMaskedTextBox", Description = "The C1MaskedTextBox control prevents users from entering invalid characters with masking." },
                    new SampleSpec() { Title = "numeric", FullTypeName = "ControlExplorer.Controls.NumericBox.NumericBoxDemo", Thumbnail="inputNumericBox", Description = "The C1NumericBox control displays and edits formatted values such as currencies and percentages." }
                },
                Categories = { ControlCat.all, ControlCat.input }
            });
            Controls.Add(new ControlViewModel("LayoutPanels")
            {
                SampleSpecs =
                {
                    new SampleSpec() { Title = "dock", FullTypeName = "ControlExplorer.Controls.LayoutPanels.DemoDockPanel", Thumbnail="layoutpanelsDock", Description = "Dock content along the top, left, right and bottom edges of the screen with the C1DockPanel control." },
                    new SampleSpec() { Title = "uniform", FullTypeName = "ControlExplorer.Controls.LayoutPanels.DemoUniformGrid", Thumbnail="layoutpanelsUniform", Description = "Neatly display child elements in columns and rows with the C1UniformGrid control." },
                    new SampleSpec() { Title = "wrap", FullTypeName = "ControlExplorer.Controls.LayoutPanels.DemoWrapPanel", Thumbnail="layoutpanelsWrap", Description = "Create flow type layouts that wrap content vertically or horizontally using the C1WrapPanel control." }
                },
                Categories = { ControlCat.all }
            });
            Controls.Add(new ControlViewModel("ListBox")
            {
                SampleSpecs =
                {
                    new SampleSpec() 
                    { 
                        Title = "flickr photo viewer",
                        FullTypeName = "ControlExplorer.Controls.ListBox.ListBoxSample",
                        Thumbnail = "listbox",
                        Description = "Displays a list of photos from flickr, which can be zoomed by pinching",
                    },
                    new SampleSpec() 
                    { 
                        Title = "youtube video viewer",
                        FullTypeName = "ControlExplorer.TileListBoxSample",
                        Thumbnail = "tilelistbox",
                        Description = "Displays a list of videos from youtube in three columns",
                    },
                },
                Categories = { ControlCat.all, ControlCat.data }
            });

            Controls.Add(new ControlViewModel("Maps")
            {
                SampleSpecs =
                {
                    new SampleSpec() { Title = "bing", FullTypeName = "ControlExplorer.Controls.Maps.DemoMaps", Thumbnail = "mapBing", Description = "Get smooth zooming, panning and mapping between screen and geographical coordinates." },
                    new SampleSpec() { Title = "layers", FullTypeName = "ControlExplorer.Controls.Maps.Layers", Thumbnail = "mapLayers", Description = "Superimpose your own custom elements to the maps." },
                    new SampleSpec() { Title = "custom tiles", FullTypeName = "ControlExplorer.Controls.Maps.CustomTiles", Thumbnail = "mapCustomTiles", Description = "Display map tiles from various sources." },
                    new SampleSpec() { Title = "kml", FullTypeName = "ControlExplorer.Controls.Maps.VectorMap", Thumbnail = "mapKml", Description = "Import common geographic files in KML and KMZ formats." },
                },
                Categories = { ControlCat.all, ControlCat.favorites, ControlCat.data }
            });
            Controls.Add(new ControlViewModel("Pdf")
            {
                SampleSpecs =
                {
                    new SampleSpec() { Title = "", FullTypeName = "ControlExplorer.Controls.Pdf.DemoPdf", Description = "" },
                },
                Categories = { ControlCat.all, ControlCat.libraries }
            });
            Controls.Add(new ControlViewModel("PdfViewer")
            {
                SampleSpecs =
                {
                    new SampleSpec() { Title = "", FullTypeName = "ControlExplorer.Controls.PdfViewer.DemoPDFViewer", Description = ""},
                },
                Categories = { ControlCat.all, ControlCat.favorites }
            });
            Controls.Add(new ControlViewModel("RichTextBox")
            {
                SampleSpecs =
                {
                    new SampleSpec() { Title = "input", FullTypeName = "ControlExplorer.Controls.RichTextBox.DemoRichTextBox", Thumbnail = "richtextboxInput", Description = "Edit HTML or RTF text with support for common commands such as bold, italic and underline." },
                    new SampleSpec() { Title = "formatting", FullTypeName = "ControlExplorer.Controls.RichTextBox.RichTextBoxFormatting", Thumbnail = "richtextboxFormatting", Description = "Display formatted text as HTML or RTF with support for most common tags." },
                    new SampleSpec() { Title = "facebook feed", FullTypeName = "ControlExplorer.Controls.RichTextBox.FacebookRSS", Thumbnail = "richtextboxFacebookFeed", Description = "Display HTML content from RSS feeds such as Facebook and Twitter." },
                    new SampleSpec() { Title = "syntax highlight", FullTypeName = "ControlExplorer.Controls.RichTextBox.SyntaxHighlight", Thumbnail = "richtextboxSyntaxHightLight", Description = "Customize the control to look like a code editor." },
                },
                Categories = { ControlCat.all, ControlCat.favorites, ControlCat.input }
            });
            Controls.Add(new ControlViewModel("Tile")
            {
                SampleSpecs =
                {
                    new SampleSpec() 
                    { 
                        Title = "tile types",
                        FullTypeName = "ControlExplorer.Controls.Tile.TileTypes",
                        Thumbnail = "tiletypes",
                        Description = "Shows different tile types with different settings",
                    },
                    new SampleSpec() 
                    { 
                        Title = "flickr tags",
                        FullTypeName = "ControlExplorer.Controls.Tile.ContentSourceSample",
                        Thumbnail = "flickrtags",
                        Description = "Shows C1 tiles with ContentSource set",
                    },
                    new SampleSpec() 
                    { 
                        Title = "photo viewer",
                        FullTypeName = "ControlExplorer.Controls.Tile.ListBoxSample",
                        Thumbnail = "photoviewer",
                        Description = "Shows C1FlipTile control as ItemTemplate in the ListBox. Also demonstrates how to bind custom delegate command to C1Tile control",
                    },
                },
                Categories = { ControlCat.all, ControlCat.favorites }
            });

            Controls.Add(new ControlViewModel("Zip")
            {
                SampleSpecs =
                {
                    new SampleSpec() { Title = "", FullTypeName = "ControlExplorer.Controls.Zip.DemoZip", Description = "" }
                },
                Categories = { ControlCat.all, ControlCat.libraries }
            });
            #endregion

            // fill categories
            foreach (var category in Extensions.GetEnumValues<ControlCat>(typeof(ControlCat)))
            {
                var item = new CategoryViewModel() { Category = category };
                foreach (var control in Controls.Where(c => c.Categories.Contains(category)))
                {
                    item.Controls.Add(control);
                }
                Categories.Add(item);
            }
        }


        /// <summary>
        /// Gets or sets the version of the suite bein showcased.
        /// </summary>
        /// <value>The controls version.</value>
        public string ControlsVersion { get; set; }

        /// <summary>
        /// Gets or sets the state of the sample.
        /// Used when samples go to dormant state, for instance, when lunching a chooser.
        /// </summary>
        /// <value>The state of the sample.</value>
        public object SampleState { get; set; }


        bool _inheritPhoneTheme;

        /// <summary>
        /// Gets or sets a value indicating whether to inherit or not the phone theme for this app.
        /// </summary>
        /// <value><c>true</c> if is inheriting the phone theme; otherwise, <c>false</c>.</value>
        public bool InheritPhoneTheme
        {
            get
            {
                return _inheritPhoneTheme;
            }
            set
            {
                if (_inheritPhoneTheme != value)
                {
                    _inheritPhoneTheme = value;
                    UpdateApplicationTheme();

                    if (PropertyChanged != null)
                    {
                        PropertyChanged(this, new PropertyChangedEventArgs("InheritPhoneTheme"));
                    }
                }
            }
        }


        const string ControlExplorerThemeUri = "/ControlExplorer;component/Themes/ControlExplorerTheme.xaml";
        const string LightThemeUri = "/ControlExplorer;component/Themes/LightTheme.xaml";
        const string DarkThemeUri = "/ControlExplorer;component/Themes/DarkTheme.xaml";

        /// <summary>
        /// Updates the application theme.
        /// </summary>
        internal void UpdateApplicationTheme()
        {
            if (Application.Current.Resources.MergedDictionaries.Count != 2)
                throw new InvalidOperationException("Update this if you change the MergedDictionaries used in the App.xaml");


            var appMergedDictionaries = Application.Current.Resources.MergedDictionaries;
            appMergedDictionaries.RemoveAt(1);
            if (InheritPhoneTheme)
            {
                if (ApplicationHelper.IsLightTheme)
                {
                    appMergedDictionaries.Add(new ResourceDictionary() { Source = new Uri(LightThemeUri, UriKind.RelativeOrAbsolute) });
                }
                else
                {
                    appMergedDictionaries.Add(new ResourceDictionary() { Source = new Uri(DarkThemeUri, UriKind.RelativeOrAbsolute) });
                }
            }
            else
            {
                appMergedDictionaries.Add(new ResourceDictionary() { Source = new Uri(ControlExplorerThemeUri, UriKind.RelativeOrAbsolute) });
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }


    public enum ControlCat
    {
        all,
        favorites,
        data,
        input,
        libraries
    }
}
